import {isArr} from "@/utils/arrayUtil";
import {intersect, Point, union, getGraphicList} from 'lark-map'
import {GEOMETRY_DATA_FILED} from "@/views/business/constantData";
import {GET_LOCATE_SYMBOL} from "@/utils/SymbolUtils";

const pageBaseMapMixins = {
  props: {
    baseMap: {
      type: Object, default: () => {
      }
    }
  },
  data() {
    return {
      areaFiled: 'geometryArea'
    }
  },
  watch: {
    baseMap(val) {
      if (val && this.initMonitor && typeof this.initMonitor == 'function') {
        this.initMonitor()
      }
    }
  },
  methods: {
    /**
     * 添加图层或向已存在的图层中添加数据
     * @param layerId
     * @param source
     * @param rendererSymbol
     * @param geometryType
     * @param txtFileList
     * @param txtColor
     * @param fontSize
     * @returns {Promise<unknown>}
     */
    addLayer({layerId, source, rendererSymbol, geometryType = 'polygon', txtFileList = [], txtColor, fontSize}) {
      let owner = this
      this.startLoading()
      return new Promise(async (resolve, reject) => {
        if (!isArr(source)) {
          owner.endLoading()
          resolve()
          return
        }
        let currentLayer = owner.baseMap.findLayerById(layerId)
        if (currentLayer) {
          await owner.baseMap.addFeature(layerId, source);
          owner.endLoading()
          resolve()
        } else {
          const fields = source[0].attributes && isArr(Object.keys(source[0].attributes)) ? _.map(Object.keys(source[0].attributes), key => {
            return {
              name: key, alias: key, type: 'string'
            }
          }) : []
          owner.baseMap.addFeatureLayer({
            source,
            fields,
            layerId,
            rendererSymbol,
            visible: true,
            opacity: 1,
            geometryType,
            txtFileList,
            txtColor,
            fontSize
          })
          owner.endLoading()
          resolve()
        }
      })
    },

    /**
     * 删除图层
     * @param layerId
     */
    removeLayer({layerId}) {
      this.baseMap.removeFeatureLayer({layerId})
    },


    /**
     * 删除数据
     * @param layerId
     * @param geometry
     * @param where
     * @returns {Promise<unknown>}
     */
    async delFeaturesByGeometryAndWhere({layerId, geometry, where}) {
      let owner = this
      return new Promise(async (resolve, reject) => {
        let features = await owner.getGraphicByGeometryAndWhere({layerId, geometry, where});
        if (!isArr(features)) {
          resolve()
          return
        }
        await owner.delFeatures({features, layerId});
        resolve()
      })
    },

    /**
     * 删除数据
     * @param features
     * @param layerId
     */
    async delFeatures({features, layerId}) {
      let owner = this
      return new Promise(async (resolve, reject) => {
        await owner.baseMap.delFeature({layerId, features});
        resolve()
      })
    },

    /**
     * 清除渲染物
     */
    removeRender(){
      this.closeMapPopup()
      this.removeMapHighlight()
    },

    /**
     * 针对某一图层开启点击监听
     * @param layerId
     * @param backFun
     */
    openMonitor({layerId, backFun}) {
      if (this.baseMap.checkMonitorByLayerId({layerId, backFun})) {
        this.baseMap.removeMonitorByLayerId({layerId, backFun})
      }
      this.baseMap.addMonitorByLayerId({layerId, backFun})
    },


    /**
     * 裁剪查询
     * @param layerId
     * @param graphic
     * @param where
     * @param cutting
     * @returns {Promise<unknown>}
     */
    getCuttingGraphicByGeometryAndWhere({layerId, geometry:baseGeometry, where, cutting = false}) {
      let owner = this
      return new Promise(async (resolve, reject) => {
        let features = await owner.getGraphicByGeometryAndWhere({layerId, geometry:baseGeometry, where})
        features = cutting ? features.map(item => {
          let {geometry} = item
          item.geometry = intersect({geometry: baseGeometry, intersector: geometry});
          return item;
        }) : features
        resolve(features);
      })
    },

    /**
     * 通用查询
     * @param layerId
     * @param graphic
     * @param where
     * @param cutting
     * @returns {Promise<unknown>}
     */
    getGraphicByGeometryAndWhere({layerId, geometry, where}) {
      let owner = this
      return new Promise(async (resolve, reject) => {
        let layer = owner.baseMap.findLayerById(layerId);
        if (!layer) {
          resolve([]);
          return
        }
        let res = await owner.baseMap.queryFeature({layer, geometry, where})
        if (!isArr(res.features)) {
          resolve([]);
          return
        }
        let {features} = res
        resolve(features);
      })
    },

    /**
     * 打开地图弹框
     * @param layerId
     * @param features
     * @param point
     */
    openPopup(layerId, features, point, popupTitle) {
      let geometry = features[0].geometry
      this.baseMap.highlight(geometry)
      this.baseMap.openPopup(layerId,features, point, popupTitle)
    },

    /**
     *定位
     * @param layerId
     * @param where
     * @param openPopupFlag
     * @param popupTitle
     */
    async locationByWhere({layerId, where, openPopupFlag, popupTitle}) {
      let features = await this.getGraphicByGeometryAndWhere({layerId, where});
      if (!isArr(features)) return;
      await this.locationByFeatures({layerId, features, openPopupFlag, popupTitle})
    },

    /**
     *定位
     * @param layerId
     * @param features
     * @param openPopupFlag
     * @param popupTitle
     * @param point
     */
    async locationByFeatures({layerId, features, openPopupFlag, popupTitle, point}) {
      if (features.length > 1) {
        let geometryList = _.map(features, feature => feature.geometry)
        let unionGeometry = union(geometryList)
        await this.baseMap.goToGeometry(unionGeometry)
        this.baseMap.highlight(unionGeometry)
      } else {
        let [{geometry}] = features;
        await this.baseMap.goToGeometry(geometry)
        if (openPopupFlag) {
          point = point || this.getPointByFeatures(features)
          this.openPopup(layerId, features, point, popupTitle)
        }
      }
    },

    /**
     * 根据查询结果，获取第一条数据的中心点
     * @param features
     * @returns {*}
     */
    getPointByFeatures(features) {
      let [{geometry, geometry: {type, extent}}] = features;
      let point = geometry = type === 'point' ? geometry : new Point({
        spatialReference: {wkid: 4490},
        x: extent.center.x,
        y: extent.center.y,
        longitude: extent.center.x,
        latitude: extent.center.y
      })
      return point
    },

    /**
     * 为数据添加面积属性
     * @param features
     */
    setAreaToFeatures(features) {
      if (!isArr(features)) return;
      let owner = this
      _.forEach(features, feature => {
        let {geometry} = feature;
        feature.attributes[owner.areaFiled] = owner.baseMap.getAreaByGeometry(geometry)
      })
    },


    /**
     * 获取总面积
     * @param features
     * @returns {number}
     */
    getSumAreaByFeatures(features) {
      if (!isArr(features)) return;
      let res = this.baseMap.getAreaByGeometryList(_.map(features, feature => feature.geometry))
      let {sumArea} = res
      return sumArea;
    },

    /**
     * 根据查询条件获取面积
     * @param layerId
     * @param where
     * @param geometry
     * @returns {Promise<unknown>}
     */
    async getSumAreaByLayerIdAndQueryParam({layerId, where, geometry}) {
      let owner = this
      let layer = this.baseMap.findLayerById(layerId);
      return new Promise(async (resolve, reject) => {
        let sumArea = 0;
        if (!layer) {
          resolve(sumArea)
          return
        }
        let features = await owner.getGraphicByGeometryAndWhere({layerId, where, geometry});
        sumArea = owner.getSumAreaByFeatures(features)
        resolve(sumArea)
      });
    },

    /**
     * 添加数据到地图上
     * @param layerId
     * @param rendererSymbol
     * @param graphicList
     * @param geometryType
     * @param txtFileList
     * @param txtColor
     * @returns {Promise<unknown>}
     */
    async addLayerByGraphicData({layerId, rendererSymbol, graphicList, geometryType, txtFileList,txtColor = '#000'}) {
      let owner = this
      return new Promise(async (resolve, reject) => {
        if (!isArr(graphicList)) {
          resolve()
          return
        }
        let features = this.getFeaturesByGraphicList(graphicList,geometryType)
        await owner.addLayer({
          layerId,
          source: features,
          rendererSymbol: rendererSymbol || GET_LOCATE_SYMBOL(geometryType),
          geometryType,
          txtFileList,
          txtColor,
          fontSize: 15
        })
        resolve()
      })

    },

    getFeaturesByGraphicList(graphicList,geometryType){
      const config = [];
      _.forEach(graphicList, graphicData => {
        let {attributes, geoData,} = graphicData;
        config.push({
          attributes,
          geometryType,
          [GEOMETRY_DATA_FILED[geometryType]]: JSON.parse(geoData)
        })
      })
      return getGraphicList({config, spatialReference: {wkid: 4490}});
    },

    /**
     *等待地图加载
     * @returns {Promise<unknown>}
     */
    awaitMapLoaded() {
      let owner = this
      return new Promise((resolve, reject) => {
        let time = setInterval(() => {
          console.log('mapLoad')
          if (owner.baseMap) {
            clearInterval(time)
            resolve()
          }
        }, 1);
      })
    },

    /**
     * 关闭弹框
     */
    closeMapPopup() {
      this.baseMap.closePopup()
    },

    /**
     * 清除高亮
     */
    removeMapHighlight() {
      this.baseMap.removeHighlight()
    }
  },
}

export {pageBaseMapMixins}
